package com.scut.online_black_market.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.scut.online_black_market.dto.*;
import com.scut.online_black_market.entity.Personal;
import com.scut.online_black_market.entity.ProductOrder;
import com.scut.online_black_market.entity.ProductSellout;
import com.scut.online_black_market.entity.ShoppingGuide;
import com.scut.online_black_market.exception.AskForProductException;
import com.scut.online_black_market.exception.BalanceException;
import com.scut.online_black_market.exception.SellProductException;
import com.scut.online_black_market.exception.UniversalException;
import com.scut.online_black_market.mapper.PersonalMapper;
import com.scut.online_black_market.mapper.ProductOrderMapper;
import com.scut.online_black_market.mapper.ProductSelloutMapper;
import com.scut.online_black_market.mapper.ShoppingGuideMapper;
import com.scut.online_black_market.service.ProductTradeService;
import com.scut.online_black_market.utility.JwtUtil;
import com.scut.online_black_market.utility.RedisUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * create by yellowBroke on 2020年10月12日 17点08分
 * 商品交易服务实现
 */

@Service
public class ProductTradeServiceImpl implements ProductTradeService {

    @Resource
    private ProductSelloutMapper productSelloutMapper;

    @Resource
    private ShoppingGuideMapper shoppingGuideMapper;

    @Resource
    private PersonalMapper personalMapper;

    @Resource
    private ProductOrderMapper productOrderMapper;

    @Resource
    private HttpServletRequest httpServletRequest;

    @Resource
    private JwtUtil jwtUtil;

    @Resource
    private RedisUtil redisUtil;



    @Override
    public void sellProduct(ProductInfo productInfo) throws SellProductException {

        String studentNumber = jwtUtil.extractStudentNumber(httpServletRequest);
        if (!studentNumber.equals(productInfo.getSellManId())){
            throw new SellProductException("学号错误!");
        }

        ProductSellout productSellout = ProductSellout.builder()
                .productName(productInfo.getProductName())
                .productPrice(productInfo.getProductPrice())
                .productPictureLocation(productInfo.getProductPictureLocation())
                .productDescription(productInfo.getProductDescription())
                .productStatus(1)
                .sellTime(LocalDateTime.now())
                .sellmanId(studentNumber)
                .campus(productInfo.getCampus())
                .nickname(new String())
                .pictureUrl(new String())
                .build();

        if (productSelloutMapper.insert(productSellout) != 1)
            throw new SellProductException("上架商品异常");

    }

    @Override
    public IPage<ProductSellout> queryProductByPage(int pageNo, int pageSize, int queryType) {
        IPage<ProductSellout> page = new Page<>(pageNo, pageSize);

        QueryWrapper<ProductSellout> wrapper = new QueryWrapper<>();
        wrapper.eq("product_status", 1);

        switch (queryType){
            case 1:
                break;
            case 2:
                wrapper.eq("campus","南校");
                break;
            case 3:
                wrapper.eq("campus","北校");
                break;
            case 4:
                wrapper.orderByAsc("product_price");
                break;
            case 5:
                wrapper.orderByDesc("product_price");
                break;
        }
        productSelloutMapper.selectPage(page, wrapper);

        for (ProductSellout record: page.getRecords()){
            String studentNumber = record.getSellmanId();
            if (redisUtil.hasKey(studentNumber)){
                PictureAndName pictureAndName = (PictureAndName) (redisUtil.get(studentNumber));
                record.setPictureUrl(pictureAndName.getPictureUrl());
                record.setNickname(pictureAndName.getNickname());
            }
        }
        return page;
    }

    @Override
    public ProductResponse queryById(long productId) throws UniversalException {

        ProductSellout product = productSelloutMapper.selectById(productId);

        if (product == null) {
            throw new UniversalException("该商品不存在");
        }

        ProductResponse productResponse = ProductResponse.builder()
                .productName(product.getProductName())
                .productDescription(product.getProductDescription())
                .productPictureLocation(product.getProductPictureLocation())
                .build();

        return productResponse;
    }

    @Override
    public void askForProduct(ShoppingGuideInfo shoppingGuideInfo)throws AskForProductException{
        String studentNumber = jwtUtil.extractStudentNumber(httpServletRequest);

        Personal personal = personalMapper.selectById(studentNumber);

        if (personal == null) {
            throw new AskForProductException("余额不足");
        }

        if (personal.getBalance()-shoppingGuideInfo.getShoppingGuidePrice() >= 0)
            personal.setBalance(personal.getBalance()-shoppingGuideInfo.getShoppingGuidePrice());

        ShoppingGuide shoppingGuide=ShoppingGuide.builder()
                .shoppingGuideName(shoppingGuideInfo.getShoppingGuideName())
                .shoppingGuidePrice(shoppingGuideInfo.getShoppingGuidePrice())
                .shoppingGuidePictureLocation(shoppingGuideInfo.getShoppingGuidePictureLocation())
                .shoppingGuideProductStatus(1)
                .shoppingGuideDescription(shoppingGuideInfo.getShoppingGuideDescription())
                .shoppingGuideTime(LocalDateTime.now())
                .shoppingGuideBuyerId(studentNumber)
                .campus(shoppingGuideInfo.getCampus())
                .build();



        if(shoppingGuideMapper.insert(shoppingGuide)!=1||personalMapper.updateById(personal)!=1){
            throw new AskForProductException("发布求购商品失败");
        }
    }

    /**
     * created by xxl at 2020/11/21-9:19
     */
    @Override
    public SuccessResponse sell(long shoppingGuideId) throws UniversalException {

        String studentNumber = jwtUtil.extractStudentNumber(httpServletRequest);

        ShoppingGuide product = shoppingGuideMapper.selectById(shoppingGuideId);
        if (product == null)
            throw new UniversalException("该商品不存在");
        if (product.getShoppingGuideProductStatus() == 0)
            throw new UniversalException("该商品已取消求购");

        // 商品的价格
        float productPrice = product.getShoppingGuidePrice();
        Personal sellMan = personalMapper.selectById(studentNumber);

        if (sellMan == null)
            throw new UniversalException("求购用户不存在");

        //构造订单
        ProductOrder productOrder = ProductOrder.builder()
                .productId(shoppingGuideId)
                .buyerId(product.getShoppingGuideBuyerId())
                .sellmanId(studentNumber)
                .orderPrice(productPrice)
                .buyTime(LocalDateTime.now())
                .state(1)
                .type(2)//表示是求购的商品
                .build();

        // 下架求购商场的商品
        product.setShoppingGuideProductStatus(0);
        if (productOrderMapper.insert(productOrder) != 1 || shoppingGuideMapper.updateById(product) != 1){
            throw new UniversalException("向求购者发出出售请求失败，请重试");
        }


        return new SuccessResponse(true, "成功向求购者发出出售请求");
    }

    /**
     * created by xxl at 2020/11/21-10:16
     * 求购方确认收到报价
     */
    @Override
    public SuccessResponse shoppingGuideTradeFinished(long productId) throws UniversalException {

        String studentNumber = jwtUtil.extractStudentNumber(httpServletRequest);

        QueryWrapper<ProductOrder> qw=new QueryWrapper<>();
        qw.eq("product_id",productId);
        ProductOrder productOrder = productOrderMapper.selectOne(qw);

        if(productOrder == null)
            throw new UniversalException("该订单不存在");
        if (!studentNumber.equals(productOrder.getBuyerId()))
            throw new UniversalException("只有购买人才能确认收货");

        // 修改订单状态
        productOrder.setState(0);

        // 修改卖家余额
        String sellmanId = productOrder.getSellmanId();
        Personal sellman = personalMapper.selectById(sellmanId);
        sellman.setBalance(sellman.getBalance() + productOrder.getOrderPrice());
        if (personalMapper.updateById(sellman) != 1 || productOrderMapper.updateById(productOrder) != 1){
            throw new UniversalException("确认订单失败");
        }

        return new SuccessResponse(true,"求购方确认收货，请求成功，求购订单已完成");
    }

    @Override
    public SuccessResponse purchase(long productId, String buyerId, String sellmanId)
            throws UniversalException, BalanceException {
        String studentNumber = jwtUtil.extractStudentNumber(httpServletRequest);
        if (!studentNumber.equals(buyerId)){
            throw new UniversalException("buyerId错误");
        }
        ProductSellout product = productSelloutMapper.selectById(productId);
        if (product == null)
            throw new UniversalException("该商品不存在");
        if (product.getProductStatus() == 0)
            throw new UniversalException("该商品已下架");

        float productPrice = (float)product.getProductPrice();
        Personal buyer= personalMapper.selectById(buyerId);

        if (buyer == null)
            throw new UniversalException("该用户不存在");
        if(buyer.getBalance()<productPrice)//检查账户余额
        {
            throw new BalanceException("余额不足");
        }
        buyer.setBalance(buyer.getBalance()-productPrice);

        //检查订单表
        Map<String,Object> columnMap = new HashMap<>();
        columnMap.put("product_id",productId);//写表中的列名
        columnMap.put("sellman_id",sellmanId);
        columnMap.put("buyer_id",buyerId);
        List<ProductOrder> productOrderList = productOrderMapper.selectByMap(columnMap);
        if(productOrderList.size()!=0)
            throw new UniversalException("该订单已存在");
        //插入订单
        ProductOrder productOrder = ProductOrder.builder()
                .productId(productId)
                .buyerId(buyerId)
                .sellmanId(sellmanId)
                .buyTime(LocalDateTime.now())
                .orderPrice(productPrice)
                .state(0)
                .type(1)
                .build();
        productOrderMapper.insert(productOrder);
        //下架商品
        product.setProductStatus(0);
        productSelloutMapper.updateById(product);

        //减少余额
        personalMapper.updateById(buyer);

        //返回response
        SuccessResponse successResponse =SuccessResponse.builder()
                .success(true)
                .message("创建成功，灰常完美")
                .status((short) 200)
                .build();
        return successResponse;
    }

    @Override
    public SuccessResponse tradeFinished(long productId) throws UniversalException {
        String studentNumber = jwtUtil.extractStudentNumber(httpServletRequest);
        QueryWrapper<ProductOrder> qw=new QueryWrapper<>();
        qw.eq("product_id",productId);
        ProductOrder productOrder = productOrderMapper.selectOne(qw);
        if(productOrder == null)
        {
            throw new UniversalException("该订单不存在");
        }
        if (!studentNumber.equals(productOrder.getBuyerId())){
            throw new UniversalException("只有购买人才能确认收货");
        }
        //修改订单状态
        productOrder.setState(1);
        productOrderMapper.updateById(productOrder);

        //修改卖家余额
        String sellmanId= productOrder.getSellmanId();
        Personal sellman= personalMapper.selectById(sellmanId);
        sellman.setBalance(sellman.getBalance() + productOrder.getOrderPrice());
        personalMapper.updateById(sellman);

        return new SuccessResponse(true,"请求成功，订单已完成");

    }

    @Override
    public IPage<ShoppingGuideResponse> queryShoppingGuideByPage(short pageNo, short pageSize, short typeId)  {

        IPage<ShoppingGuideResponse> page = new Page<>(pageNo, pageSize);

        switch (typeId)
        {
            case 2:
                return shoppingGuideMapper.selectType2(page);

            case 3:
                return shoppingGuideMapper.selectType3(page);

            case 4:
                return shoppingGuideMapper.selectType4(page);

            case 5:
                return shoppingGuideMapper.selectType5(page);

            default:
                return shoppingGuideMapper.selectType1(page);
        }
    }



}
